package com.quectel.sdk.kuangshi;

import com.fasterxml.jackson.core.type.TypeReference;
import com.quectel.sdk.kuangshi.basemodel.KsBaseResp;
import com.quectel.util.ex.CheckErrorException;
import com.quectel.util.http.HttpRestUtils;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 在这里编写说明
 *
 * @author: rananxin
 * @email: ryan.ran@quectel.com
 * @date: 2022-10-19 11:01:00
 */
public class ksRequester {

    private static final Logger logger = LoggerFactory.getLogger(ksRequester.class);

    private static Map<String, HttpRestUtils> REST_UTIL_MAP = new ConcurrentHashMap<>();

    private final HttpRestUtils HTTP_REST_UTILS;

    private final String baseUrl;
    private final String username;
    private final String password;

    private ksRequester(String baseUrl, String username, String password) {
        this.baseUrl = baseUrl;
        this.username = username;
        this.password = password;

        HTTP_REST_UTILS = REST_UTIL_MAP.computeIfAbsent(baseUrl, key -> {
            SSLContext sslContext = null;
            try {
                sslContext = SSLContexts.custom().loadTrustMaterial(null, (TrustStrategy) (x509Certificates, s) -> true).build();
            } catch (Exception e) {
                e.printStackTrace();
            }

            RequestConfig defaultRequestConfig = RequestConfig.custom()
                    .setSocketTimeout(5000)
                    .setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000)
                    .build();

            CredentialsProvider credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
            HttpClient sslHttpClient = HttpClients.custom()
                    .setDefaultRequestConfig(defaultRequestConfig)
                    .setSslcontext(sslContext)
                    .setSSLHostnameVerifier(new NoopHostnameVerifier())
                    .setMaxConnTotal(500)
                    .setMaxConnPerRoute(100)
                    //重试1次
                    .setRetryHandler(new DefaultHttpRequestRetryHandler(5, false))
                    .setDefaultCredentialsProvider(credsProvider)
                    .build();
            return HttpRestUtils.getInstance(sslHttpClient);
        });
    }

    public static ksRequester getInstance(String baseUrl, String username, String password) {

        return new ksRequester(baseUrl, username, password);
    }

    public <T> KsBaseResp<T> get(String path, Map<String, Object> params, TypeReference<KsBaseResp<T>> typeReference) {
        if (this.baseUrl == null) {
            throw new CheckErrorException("checked url " + baseUrl + " is null");
        }
        List<NameValuePair> paramList = new ArrayList<>();
        if (params != null) {
            Set<Map.Entry<String, Object>> entries = params.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                paramList.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
            }
        }
        return HTTP_REST_UTILS.get(baseUrl + path, paramList, null, typeReference).getRight();
    }

}
